package snafu.implementation.worlds;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.util.List;

import snafu.framework.objects.WorldObject;
import snafu.framework.worlds.WorldMapPanel;
import snafu.implementation.states.literals.color.ColorLiteral;
import snafu.implementation.states.literals.direction.DirectionLiteralItself;
import snafu.implementation.states.literals.shape.ShapeLiteral;

public class HexWorldMapPanel extends WorldMapPanel {
	public HexWorldMapPanel(HexWorldMap map) {
		super(map);
	}
	
	@Override
	protected void paintObjects(List<WorldObject> objects, Point2D tileSize, Color borderColor, Graphics g) {
		// calc hex coordinates
		int[] xPoints = new int[] {
				(int) (HexWorldMap.R * tileSize.getX()), 
				(int) (HexWorldMap.A * tileSize.getX()), 
				(int) (HexWorldMap.A * tileSize.getX()), 
				(int) (HexWorldMap.R * tileSize.getX()), 
				0, 
				0
		};
		int[] yPoints = new int[] {
				0,
				(int) (HexWorldMap.H * tileSize.getX()),
				(int) ((HexWorldMap.H + HexWorldMap.S) * tileSize.getX()),
				(int) (HexWorldMap.B * tileSize.getX()),
				(int) ((HexWorldMap.H + HexWorldMap.S) * tileSize.getX()),
				(int) (HexWorldMap.H * tileSize.getX())
		};
		Shape defaultShape = new Polygon(xPoints, yPoints, 6);
		
		// get 2D graphics and set anti-aliasing on
		Graphics2D g2d = (Graphics2D) g;
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

		// draw objects
		for (WorldObject object : objects) {
			// get color from literals
			Color color = object.getState().getLiteral(ColorLiteral.class, Color.GRAY);
			g2d.setColor(color);

			// get shape
			Shape shape = object.getState().getLiteral(ShapeLiteral.class);

			// draw full tile shape
			if (shape == null) {
				g2d.fill(defaultShape);
			// draw custom shape
			} else {
				// save current transformation
				AffineTransform currentTransformation = g2d.getTransform();
				
				// rotate object
				Integer direction = object.getState().getLiteral(DirectionLiteralItself.class);
				if (direction != null) {
					double angle = Math.PI / 3 * direction + Math.PI / 6;
					g2d.rotate(angle, tileSize.getX() / 2, tileSize.getY() / 2);
				}
				// scale object
				double scale = tileSize.getX() * 0.8 / 100;
				g2d.scale(scale, scale);
				
				// translate object
				double translateX = (tileSize.getX() - scale) / 2 / scale;
				double translateY = (tileSize.getY() - scale) / 2 / scale;
				g2d.translate(translateX, translateY);
				
				// draw object
				g2d.fill(shape);
				
				// restore current transformation
				g2d.setTransform(currentTransformation);
			}
		}
		
		// draw border
		g2d.setColor(borderColor);
		g2d.draw(defaultShape);
		
	}

}
